package com.yuneec.fly.utils;

import android.os.Handler;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.yuneec.droneservice.ServiceManager;
import com.yuneec.droneservice.command.BindCamera;
import com.yuneec.droneservice.command.CommandListener;
import com.yuneec.droneservice.command.GetCameraInfo;
import com.yuneec.droneservice.command.ScanCamera;
import com.yuneec.droneservice.command.UnbindCamera;
import com.yuneec.droneservice.model.CameraInfo;
import com.yuneec.droneservice.model.CameraScanResult;
import com.yuneec.droneservice.request.IResponse;
import com.yuneec.droneservice.request.OnRequestListener;
import com.yuneec.fly.DroneApplication;
import com.yuneec.fly.events.EventBusFactory;
import com.yuneec.fly.events.commandEvent.SendCommandEvent;
import com.yuneec.fly.events.uiEvent.ShowCameraIp;
import com.yuneec.fly.events.uiEvent.ShowToastEvent;
import com.yuneec.fly.utils.inject.WifiPasswordsSaver;

import java.util.ArrayList;
import java.util.List;

import static com.yuneec.fly.utils.inject.WifiPasswordsSaver.getWifiPasswords;
import static com.yuneec.fly.utils.inject.WifiPasswordsSaver.saveWifiPasswords;

/**
 * Created by gjw on 2016/12/19.
 */

public class CameraHelper {
    private static volatile CameraHelper instance;

    public interface CameraListener {
        void onFinishScan(ArrayList<CameraScanResult> wifis);

        void onReset();

        void onConnectWifiSuccess(String ssid);

        void onConnectWifiFail(int errorCode);

        void onConnectWifiTime();

    }

    private CameraListener cameraListener;
    private boolean running;
    private boolean scanning;
    private ArrayList<CameraScanResult> cameras = new ArrayList<>();
    private String[] cameraContentsStrings;
    private List<WifiPasswordsSaver.WifiPassword> wifiPasswords;
    private boolean checkRunning;
    private WifiPasswordsSaver.WifiPassword connectingWifi;


    private CameraHelper() {

    }

    public static CameraHelper getInstance() {
        if (instance == null) {
            synchronized (CameraHelper.class) {
                if (instance == null) {
                    instance = new CameraHelper();
                }
            }
        }
        return instance;
    }

    public void setCameraListener(CameraListener cameraListener) {
        this.cameraListener = cameraListener;
    }

    public List<CameraScanResult> getCameras() {
        return cameras;
    }

    public void start() {
        running = true;
        scanning = false;
    }

    public void stop() {
        running = false;
    }

    public String getCurrentBind() {
        final CameraInfo[] cameraInfo = new CameraInfo[1];
        final boolean[] getResponse = new boolean[1];
        EventBusFactory.getCommandBus().post(new SendCommandEvent(new GetCameraInfo(), new CommandListener<CameraInfo>() {
            @Override
            public void onSuccess(IResponse<CameraInfo> response) {
                CameraInfo cinfo = response.getParam();
                cameraInfo[0] = cinfo;
                getResponse[0] = true;
                ShowCameraIp scip = new ShowCameraIp();
                if (cinfo != null && !TextUtils.isEmpty(cinfo.getIp())) {
                    scip.ip = cinfo.getIp();
                }else{
                    scip.ip = "N/A";
                }
                EventBusFactory.getUiBus().post(scip);
            }

            @Override
            public void onError(int errorCode) {
                getResponse[0] = true;
            }

        }));

        for (int i = 0; i < 100; i++) {
            if (getResponse[0]) {
                break;
            }
            SystemClock.sleep(200);
        }


        if (cameraInfo[0] != null) {
//            return cameraInfo[0].getSsid()+" "+cameraInfo[0].getIp();
            return cameraInfo[0].getSsid().trim();
        }
        return null;
    }

    public void scan() {
        if (scanning) {
            return;
        }
        EventBusFactory.getUiBus().post(new ShowToastEvent("start send scan command!"));
        scanning = true;
        cameras.clear();
        EventBusFactory.getCommandBus().post(new SendCommandEvent(new ScanCamera(), new CommandListener<CameraScanResult[]>() {
            @Override
            public void onSuccess(IResponse<CameraScanResult[]> response) {
                CameraScanResult[] cams = response.getParam();
                for (CameraScanResult cam : cams) {
                    cameras.add(cam);
                }
                if (cameraListener != null) {
                    cameraListener.onFinishScan(cameras);
                }
                scanning = false;
                EventBusFactory.getUiBus().post(new ShowToastEvent("scan onSuccess"));
            }

            @Override
            public void onError(int errorCode) {
                if (cameraListener != null) {
                    cameraListener.onFinishScan(cameras);
                }
                scanning = false;
                EventBusFactory.getUiBus().post(new ShowToastEvent("scan onError " + errorCode));
            }

            @Override
            public void onTimeout() {
                if (cameraListener != null) {
                    cameraListener.onFinishScan(cameras);
                }
                scanning = false;
                EventBusFactory.getUiBus().post(new ShowToastEvent("scan onTimeout"));
            }

        }));
    }

    public void reset() {
        EventBusFactory.getCommandBus().post(new SendCommandEvent(new UnbindCamera(), new CommandListener() {
            @Override
            public void onSuccess(IResponse response) {
                removeWifiPassword(getCurrentBind());
                SharePrefUtil.saveString(DroneApplication.getApplication(), SharePrefUtil.KEY.KEY_CONNECTED_CAMERA_SSID, "");
                SharePrefUtil.saveString(DroneApplication.getApplication(), SharePrefUtil.KEY.KEY_CONNECTED_CAMERA_PASSWORD, "");
                if (cameraListener != null) {
                    cameraListener.onReset();
                }
            }
        }));
    }

    public void connectCamera(String ssid, String password) {
        connectingWifi = new WifiPasswordsSaver.WifiPassword(ssid, password);
        EventBusFactory.getCommandBus().post(new SendCommandEvent(new BindCamera(ssid, password), new CommandListener() {
            @Override
            public void onSuccess(IResponse response) {
                checkConnectStatus();
            }

            @Override
            public void onError(int errorCode) {
                if (cameraListener != null) {
                    cameraListener.onConnectWifiFail(errorCode);
                }
            }

            @Override
            public void onTimeout() {
                if (cameraListener != null) {
                    cameraListener.onConnectWifiTime();
                }
            }

        }));
    }

    private void checkConnectStatus() {
        if (checkRunning) {
            return;
        }
        checkRunning = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                long start = SystemClock.elapsedRealtime();
                boolean connected = false;
                while (running && SystemClock.elapsedRealtime() - start < 30000 && !connected) {
                    if (connectingWifi.ssid.equals(getCurrentBind())) {
                        connected = true;
                        SharePrefUtil.saveString(DroneApplication.getApplication(), SharePrefUtil.KEY.KEY_CONNECTED_CAMERA_SSID, connectingWifi.ssid);
                        SharePrefUtil.saveString(DroneApplication.getApplication(), SharePrefUtil.KEY.KEY_CONNECTED_CAMERA_PASSWORD, connectingWifi.password);

                        saveWifiPassword(connectingWifi);

                        if (cameraListener != null) {

                            cameraListener.onConnectWifiSuccess(connectingWifi.ssid);
                        }
                    }
                    if (!connected) {
                        SystemClock.sleep(1000);
                    }
                }
                if (!connected && connectingWifi.ssid != null) {
                    LogUtils.e("removeWifiPassword");
                    removeWifiPassword(connectingWifi.ssid);
                }
                if (!connected && cameraListener != null) {
                    cameraListener.onConnectWifiFail(-1);
                }
                checkRunning = false;
            }
        }).start();
    }

    private boolean isCameraWifi(String item) {
        return true;
//        if(cameraContentsStrings==null){
//            cameraContentsStrings=DroneApplication.getApplication().getResources().getStringArray(R.array.bind_wifi_camera_contents_strings);
//        }
//        if (item == null) {
//            return false;
//        }
//        for (int i = 0; i < cameraContentsStrings.length; i++) {
//            if (item.startsWith(cameraContentsStrings[i]))
//                return true;
//        }
//        return false;
    }

    public WifiPasswordsSaver.WifiPassword getPassword(String ssid) {
        if (wifiPasswords == null) {
            synchronized (this) {
                if (wifiPasswords == null) {
                    wifiPasswords = getWifiPasswords(DroneApplication.getApplication());
                }
            }
        }
        for (WifiPasswordsSaver.WifiPassword pas : wifiPasswords) {
            if (pas.ssid.equals(ssid)) {
                return pas;
            }
        }
        return null;
    }

    public void saveWifiPassword(WifiPasswordsSaver.WifiPassword pas) {
        if (wifiPasswords == null) {
            synchronized (this) {
                if (wifiPasswords == null) {
                    wifiPasswords = getWifiPasswords(DroneApplication.getApplication());
                }
            }
        }
        for (int i = wifiPasswords.size() - 1; i >= 0; i--) {
            if (wifiPasswords.get(i).ssid.equals(pas.ssid)) {
                wifiPasswords.remove(i);
                break;
            }
        }
        wifiPasswords.add(pas);
        saveWifiPasswords(DroneApplication.getApplication(), wifiPasswords);
    }

    private void removeWifiPassword(String ssid) {
        if (wifiPasswords == null) {
            synchronized (this) {
                if (wifiPasswords == null) {
                    wifiPasswords = getWifiPasswords(DroneApplication.getApplication());
                }
            }
        }
        for (int i = wifiPasswords.size() - 1; i >= 0; i--) {
            if (wifiPasswords.get(i).ssid.equals(ssid)) {
                wifiPasswords.remove(i);
                break;
            }
        }
        saveWifiPasswords(DroneApplication.getApplication(), wifiPasswords);
    }
}
